﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.Office.Interop.Word;
using QuanLyNganHangDe.DAL;
using QuanLyNganHangDe.DAL.Models;

namespace QuanLyNganHangDe.BLL
{
    /// <summary>   Lớp đọc các câu hỏi từ file *.doc
    /// </summary>
    public class WordHelper
    {
        #region Local variable
        Microsoft.Office.Interop.Word._Application wApp;
        object character = WdUnits.wdCharacter;
        object wdStory = WdUnits.wdStory;
        object oneChar = 1;
        object numchar = 0;
        object True = true;
        object False = false;
        object missing = Missing.Value;
        object countChar = 1;
        object numColumn = 3;
        object stringSeparator = WdTableFieldSeparator.wdSeparateByDefaultListSeparator;
        object charUntilBeginKey = Constant.CharBeginKey.ToString();
        object stringNeedFind = "";
        object typeDeleteCellUp = WdDeleteCells.wdDeleteCellsShiftUp;
        object typeDeleteEntiteRow = WdDeleteCells.wdDeleteCellsEntireRow;
        #endregion

        /// <summary>
        /// Lấy câu hỏi từ file "fileName" đưa vào "questions" 
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="questions"></param>
        public List<CauHoi> ReadMSWordToListQuestion(string fileName, bool coSuDungDapAn)
        {
            #region -  Khai báo & khởi gán biến  -
            object FileName = fileName;
            wApp = new Microsoft.Office.Interop.Word.Application();
            var dsCauHoi = new List<CauHoi>();

            #endregion

            try
            {

                #region Mở file .doc
                wApp.Documents.Open(ref FileName, ref missing, ref missing, ref missing,
                                     ref missing, ref missing, ref missing, ref missing,
                                     ref missing, ref missing, ref missing, ref missing,
                                     ref missing, ref missing, ref missing, ref missing
                                    );
                #endregion

                #region Biến cục bộ và các thiết lập
                wApp.Visible = false;
                //wApp.Selection.HomeKey(ref wdStory);
                bool implement = true;
                string[] partTitle = null;
                string[] content = null;
                string temp = string.Empty;
                object charUntilBetweenTitleAndContent = Constant.BetweenTitleAndContentSingleKey;
                wApp.DefaultTableSeparator = "¥";// "``";
                stringNeedFind = "[anw_start]";
                #endregion

                #region Lấy nội dung phần câu hỏi
                while (implement)
                {
                    int countTextMove = wApp.Selection.MoveUntil(ref charUntilBeginKey);
                    if (countTextMove == 0)
                        throw new Exception("Lỗi: File đầu vào không đúng định dạng (Không có ký tự kết thúc phần câu hỏi)");
                    var selectionText = wApp.Selection.Text;
                    if (selectionText == Constant.CharBeginKey.ToString())
                    {
                        int count = -1;
                        while (selectionText[selectionText.Length - 1] != Constant.CharEndKey)
                        {
                            wApp.Selection.MoveRight(ref character, ref oneChar, ref True);
                            selectionText = wApp.Selection.Text;
                            count++;
                            if (count > Constant.MaxLenthKey())
                                throw new Exception("File đầu vào chứa khóa không chính xác");
                        }
                        switch (selectionText)
                        {
                            case Constant.WordKeyPartStart:
                                wApp.Selection.MoveRight(ref character, ref oneChar, ref False);
                                partTitle = getResultForQuestion(Constant.WordKeyQuestionStart);
                                break;
                            case Constant.WordKeyQuestionStart:
                                CauHoi ch = new CauHoi();
                                Khoi khoi = new Khoi();
                                if (partTitle != null)
                                {
                                    khoi.TenKhoi = partTitle[1];//.Replace(Constant.WordKeyPartStart, "");
                                    ch.MaKhoi = khoi.TenKhoi;
                                }
                                else
                                    throw new Exception("Tên khối lỗi");
                                ///Lấy tiêu đề câu và lấy điểm
                                wApp.Selection.MoveRight(ref character, ref oneChar, ref False);
                                content = getResultForQuestion(Constant.BetweenTitleAndContentSingleKey.ToString());
                                if (content != null && content.Length == 2)
                                {
                                    //content[1] = content[1].Replace(Constant.WordKeyQuestionStart, "");
                                    var information = getQuestionInfomation(content[1]);
                                    if (information != null && information.Length == 2)
                                    {
                                        ch.TenCauHoi = information[0];
                                        khoi.SoDiem = information[1];
                                        ch.MaCauHoi = khoi.SoDiem;
                                    }
                                    else
                                        throw new Exception("Tên câu hỏi và điểm lỗi");
                                }
                                else
                                    throw new Exception("Nội dung lỗi");
                                ///Lấy nội dung
                                wApp.Selection.MoveUntil(ref charUntilBetweenTitleAndContent);
                                wApp.Selection.Move(ref character, ref oneChar);
                                content = getResultForQuestion(Constant.WordKeyQuestionEnd);
                                if (content != null && content.Length == 2)
                                {
                                    ch.NoiDungCauHoi_RTF = content[0].Replace(Constant.WordKeyQuestionStart, "");
                                    ch.NoiDungCauHoi_Unicode = content[1].Replace(Constant.WordKeyQuestionStart, "");
                                }
                                else
                                    throw new Exception("Nội dung lỗi");
                                ch.Khoi = khoi;
                                dsCauHoi.Add(ch);
                                break;
                            case Constant.WordKeyListQuestionEnd:
                                implement = false;
                                break;
                        }
                    }
                }
                #endregion

                #region Lấy nội dung phần đáp án
                implement = true;

                int startIndexOfAnwser = 0;
                while (implement && coSuDungDapAn)
                {
                    int countTextMove = wApp.Selection.MoveUntil(ref charUntilBeginKey);
                    if (countTextMove == 0)
                        throw new Exception("Lỗi: File đầu vào không đúng định dạng (Không có ký tự kết thúc phần đáp án)");
                    var selectionText = wApp.Selection.Text;
                    if (selectionText == Constant.CharBeginKey.ToString())
                    {
                        int count = -1;
                        while (selectionText[selectionText.Length - 1] != Constant.CharEndKey)
                        {
                            wApp.Selection.MoveRight(ref character, ref oneChar, ref True);
                            selectionText = wApp.Selection.Text;
                            count++;
                            if (count > Constant.MaxLenthKey())
                                throw new Exception("File đầu vào lỗi");
                        }
                        switch (selectionText)
                        {
                            case Constant.WordKeyAnwserStart:
                                wApp.Selection.MoveRight(ref character, ref oneChar, ref False);
                                content = getResultForAnwser(Constant.WordKeyAnwserEnd);
                                if (content != null && content.Length == 2)
                                {
                                    dsCauHoi[startIndexOfAnwser].NoiDungTraLoi_RTF = content[0];//.Replace(Constant.WordKeyAnwserStart, "");
                                    dsCauHoi[startIndexOfAnwser].NoiDungTraLoi_Unicode = content[1];//.Replace(Constant.WordKeyAnwserStart, "");
                                }
                                else
                                    throw new Exception("Nội dung trả lời lỗi");
                                startIndexOfAnwser++;
                                if (startIndexOfAnwser >= dsCauHoi.Count)
                                    implement = false;
                                break;
                            case Constant.WordKeyListAnwserEnd:
                                implement = false;
                                break;
                        }

                    }
                }
                #endregion

            }

            #region Handing error
            catch (Exception ex)
            {
                MessageBox.Show("Lỗi : " + ex.ToString(), "Gặp lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                missing = Missing.Value;
                wApp.Quit(ref False, ref missing, ref missing);
                //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(wApp);
                wApp = null;
            }
            #endregion
            return dsCauHoi;
        }

        /// <summary>
        /// Ghi một bộ đề ra file word
        /// </summary>
        /// <param name="fileNameTemplate"></param>
        /// <param name="listQuestion"></param>
        /// <param name="examInformation"></param>
        public void WriteListQuestionToWord(string fileNameTemplate, HocPhan hocPhan, List<CauHoi> dsCauHoi, DeInRa de)
        {
            object FileName = fileNameTemplate;
            wApp = new Microsoft.Office.Interop.Word.Application();
            try
            {

                #region Mở file .doc
                wApp.Documents.Open(ref FileName, ref missing, ref True, ref missing,
                                     ref missing, ref missing, ref missing, ref missing,
                                     ref missing, ref missing, ref missing, ref missing,
                                     ref missing, ref missing, ref missing, ref missing
                                    );
                #endregion

                #region Tìm ra thay thế các khóa
                wApp.Visible = true;
                stringNeedFind = Constant.LanThi;
                object stringWillReplace = de.LanThi;// examInformation.OrderExam;
                object typeReplace = WdReplace.wdReplaceAll;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                stringNeedFind = Constant.TenHocKy;
                stringWillReplace = "Học kỳ " + de.DotThi.HocKy.TenHocKy + ", năm học " + de.DotThi.HocKy.NamHoc.NamHoc1;//examInformation.Semester;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                stringNeedFind = Constant.NgayThi;
                stringWillReplace = de.NgayThi;// examInformation.DateExam;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                stringNeedFind = Constant.TenHocPhan;
                stringWillReplace = hocPhan.TenHocPhan;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                stringNeedFind = Constant.MaHocPhan;
                stringWillReplace = hocPhan.MaHocPhan;// examInformation.SubjectId;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                stringNeedFind = Constant.SoTinChi;
                stringWillReplace = hocPhan.SoTinChi;// examInformation.Credits;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                stringNeedFind = Constant.MaDe;
                stringWillReplace = de.MaDeThi;// examInformation.IdExam;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                stringNeedFind = Constant.ThoiGianLamBai;
                stringWillReplace = hocPhan.ThoiGianLamBai;// examInformation.TimeExam;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                stringNeedFind = Constant.LoaiDe;
                stringWillReplace = hocPhan.DuocSuDungTaiLieu ? Constant.DuocSuDungTaiLieu : Constant.KhongDuocSuDungTaiLieu;
                wApp.Selection.WholeStory();
                wApp.Selection.Find.Execute(ref stringNeedFind, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref stringWillReplace, ref typeReplace, ref missing, ref missing, ref missing, ref missing);

                #endregion

                #region Ghi danh sách các câu hỏi
                wApp.Selection.MoveLeft(ref character, ref oneChar);
                int countTextMove = wApp.Selection.MoveUntil(ref charUntilBeginKey);
                if (countTextMove == 0)
                    throw new Exception("Lỗi: Không có ký tự bắt đầu câu hỏi");
                wApp.Selection.Delete(ref character, Constant.WordKeyListQuestionStart.Length);
                foreach (var item in dsCauHoi)
                {
                    wApp.Selection.TypeText(item.TenCauHoi + " (" + item.Khoi.SoDiem + "): ");
                    Clipboard.SetText(item.NoiDungCauHoi_RTF, TextDataFormat.Rtf);
                    wApp.Selection.Paste();
                }
                #endregion

                #region Ghi danh sách các phần trả lời
                wApp.Selection.MoveRight(ref character, ref oneChar);
                countTextMove = wApp.Selection.MoveUntil(ref charUntilBeginKey);
                if (countTextMove == 0)
                    throw new Exception("Lỗi: Không có ký tự bắt đầu đáp án");
                countChar = Constant.WordKeyListAnwserStart.Length;
                wApp.Selection.MoveRight(ref character, ref countChar);
                foreach (var item in dsCauHoi)
                {
                    Clipboard.SetText(item.NoiDungTraLoi_RTF, TextDataFormat.Rtf);
                    wApp.Selection.Paste();
                    wApp.Selection.MoveRight(ref character, ref countChar, ref False);
                    wApp.Selection.TypeParagraph();
                }

                #region Chèn tiêu đề của phần bảng của đáp án
                wApp.Selection.WholeStory();
                wApp.Selection.MoveLeft(ref character);
                string strListAnwser = "";
                while (strListAnwser != Constant.WordKeyListAnwserStart)
                {
                    countTextMove = wApp.Selection.MoveUntil(ref charUntilBeginKey);
                    if (countTextMove == 0)
                        throw new Exception("Lỗi");
                    countChar = Constant.WordKeyListAnwserStart.Length;
                    wApp.Selection.MoveRight(ref character, ref countChar, ref True);
                    strListAnwser = wApp.Selection.Text;
                }
                wApp.Selection.MoveLeft(ref character);
                wApp.Selection.Delete(ref character, Constant.WordKeyListAnwserStart.Length);
                wApp.Selection.EndKey(ref wdStory, ref True);
                Table tblAnwser = wApp.Selection.Tables[1];
                tblAnwser.Cell(1, 1).Select();
                wApp.Selection.InsertRowsAbove(ref oneChar);
                Cell cellTo = tblAnwser.Cell(1, 2);
                tblAnwser.Cell(1, 1).Merge(cellTo);
                tblAnwser.Cell(1, 1).Select();
                wApp.Selection.Font.Bold = (int)WdConstants.wdToggle;
                wApp.Selection.TypeText("Nội dung trả lời");
                tblAnwser.Cell(1, 2).Select();
                wApp.Selection.TypeText("Điểm");
                #endregion

                #endregion
            }

            #region Handing error
            catch (Exception ex)
            {
                MessageBox.Show("Lỗi : " + ex.ToString(), "Gặp lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                missing = Missing.Value;
                wApp.Quit(ref False, ref missing, ref missing);
            }
            finally
            {
            }
            #endregion

        }

        #region -  Các phương thức hỗ trợ  -

        /// <summary>
        /// [0]: RTF, [1]: Normal
        /// </summary>
        /// <returns></returns>
        string[] getResultForQuestion(string stringEndKey)
        {
            try
            {
                object countChar = stringEndKey.Length;
                string[] result = new string[2];
                wApp.Selection.MoveRight(ref character, ref oneChar, ref True);
                var charResult = wApp.Selection.Text;
                while (!charResult.Contains(stringEndKey))
                {
                    int t = wApp.Selection.MoveRight(ref character, ref oneChar, ref True);
                    if (t == 0)
                        throw new Exception("Lỗi (hàm getResultForQuestion): File không chứa ký hiệu kết thúc: " + stringEndKey);
                    charResult = wApp.Selection.Text;
                }
                wApp.Selection.MoveLeft(ref character, ref countChar, ref True);
                //this.Dispatcher.BeginInvoke(new Action(() => Clipboard.SetText(splitpermutation[i])));


                wApp.Selection.Copy();
                result[0] = Clipboard.GetText(TextDataFormat.Rtf);
                result[1] = Clipboard.GetText(TextDataFormat.UnicodeText);
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception("Lỗi (hàm getResultForQuestion): File đầu vào không đúng định dạng. " + ex.ToString());
            }
        }

        string[] getResultForAnwser(string stringEndKey)
        {
            try
            {
                countChar = stringEndKey.Length;
                string[] result = new string[2];
                wApp.Selection.MoveRight(ref character, ref oneChar, ref True);
                var charResult = wApp.Selection.Text;
                while (!charResult.Contains(stringEndKey))
                {
                    int t = wApp.Selection.MoveRight(ref character, ref oneChar, ref True);
                    if (t == 0)
                        throw new Exception("Lỗi (hàm getResultForQuestion): File không chứa ký hiệu kết thúc: " + stringEndKey);
                    wApp.Selection.Copy();
                    charResult = Clipboard.GetText(TextDataFormat.Rtf);
                }
                //wApp.Selection.MoveLeft(ref character, ref countChar, ref True);

                //Table tempTable = wApp.Selection.ConvertToTable(ref stringSeparator, ref missing, ref numColumn, ref missing, ref missing, ref True);

                ///Tạo kiểu style cho table
                //object style = "Table Grid";
                //tempTable.set_Style(ref style);

                /////Trộn các ô trong cột thứ nhất
                //int numRow = tempTable.Rows.Count;
                //Cell cellEnd = tempTable.Cell(numRow, 1);
                //tempTable.Cell(1, 1).Merge(cellEnd);


                /////Xóa hàng thừa ở trên
                //tempTable.Cell(1, 2).Select();
                //wApp.Selection.Cells.Delete(ref typeDeleteCellUp);
                //tempTable.Cell(1, 3).Select();
                //wApp.Selection.Cells.Delete(ref typeDeleteCellUp);
                /////Xóa hàng thừa ở dưới khi đưa dữ liệu lên trên
                //tempTable.Cell(numRow, 2).Select();
                //wApp.Selection.Cells.Delete(ref typeDeleteEntiteRow);
                //tempTable.Select();
                //wApp.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphLeft;
                //wApp.Selection.Copy();
                result[0] = Clipboard.GetText(TextDataFormat.Rtf).Replace(Constant.WordKeyAnwserStart, "").Replace(Constant.WordKeyAnwserEnd, "");
                result[1] = Clipboard.GetText(TextDataFormat.UnicodeText).Replace(Constant.WordKeyAnwserStart, "").Replace(Constant.WordKeyAnwserEnd, "");
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception("Lỗi (hàm getResultForQuestion): File đầu vào không đúng định dạng. " + ex.ToString());
            }
        }



        /// <summary>
        /// [0] Tiêu đề câu, [1] Điểm
        /// </summary>
        /// <param name="question"></param>
        /// <returns></returns>
        string[] getQuestionInfomation(string question)
        {
            //string[] qu = question.Split(new char[] { ')' });
            //if (qu != null && qu.Length > 1)
            //{
            string[] rs = question.Split(new char[] { '(' });
            if (rs != null && rs.Length == 2)
                return rs;
            else
                return null;
            //}
            //return null;
        }
        #endregion
    }
}
